﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Xml;
using com.lover.astd.common.model;
using com.lover.astd.common.model.building;
using System.Collections;
using com.lover.astd.common.config;

namespace com.lover.astd.common.logic
{
    public class BuildingMgr : MgrBase
    {
        public BuildingMgr() { _logColor = System.Drawing.Color.DeepPink; }
        public Building getBuilding(List<Building> buildings, int buildingId)
        {
            if (buildings == null || buildings.Count == 0) return null;
            foreach (Building b in buildings) if (b.Id == buildingId) return b;
            return null;
        }
        public Building getBuilding(List<Building> buildings, string buildingName)
        {
            if (buildings == null || buildings.Count == 0) return null;
            foreach (Building b in buildings) if (b.Name.Contains(buildingName)) return b;
            return null;
        }
        private void renderBuildingNode(XmlNode building_node, List<Building> buildings)
        {
            // get id first
            int id = 0;
            XmlNode id_node = building_node.SelectSingleNode("id");
            if (id_node != null) Int32.TryParse(id_node.InnerText, out id);
            if (id == 0) return;
            Building building = getBuilding(buildings, id);
            if (building == null)
            {
                building = new Building();
                buildings.Add(building);
            }
            building.fillValues(building_node.ChildNodes);
        }
        public bool getBuildingMainCity(ProtocolMgr protocol, ILogger logger, User user)
        {
            string url = "/root/mainCity.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取玩家主城信息");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "maincitydto")
                {
                    renderBuildingNode(child, user._buildings);
                }
                else if (child.Name == "constructordto")
                {
                    updateBuildLine(child.ChildNodes, user._buildingLines);
                }
            }
            return true;
        }
        /// <summary>
        /// 获取外城信息
        /// </summary>
        /// <returns></returns>
        public bool getBuildingsOutCity(ProtocolMgr protocol, ILogger logger, User user)
        {
            string url = "/root/outCity.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取玩家外城信息");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "outcitydto")
                {
                    renderBuildingNode(child, user._buildings);
                }
                else if (child.Name == "constructordto")
                {
                    updateBuildLine(child.ChildNodes, user._buildingLines);
                }
            }
            return true;
        }
        private void updateBuildLine(XmlNodeList line_childs, Dictionary<int, BuildingLine> buildingLines)
        {
            BuildingLine line = new BuildingLine();

            foreach (XmlNode node in line_childs)
            {
                if (node.Name == "cid") line.Id = Int32.Parse(node.InnerText);
                else if (node.Name == "ctime") line.CdTime = Int64.Parse(node.InnerText);
                else if (node.Name == "cdflag") line.CdFlag = Int32.Parse(node.InnerText);
            }
            if (buildingLines.ContainsKey(line.Id))
            {
                buildingLines[line.Id].CdTime = line.CdTime;
                buildingLines[line.Id].CdFlag = line.CdFlag;
            }
            else { buildingLines.Add(line.Id, line); }
        }
        /// <summary>
        /// 升级建筑
        /// </summary>
        /// <param name="buildingId"></param>
        public bool upgradeBuilding(ProtocolMgr protocol, ILogger logger, Building building, Dictionary<int, BuildingLine> buildingLines)
        {
            string cost = building.getCost();
            string url = "/root/mainCity!upgradeLevel.action";
            if (building.IsOutCity) url = "/root/outCity!upgradeLevel.action";
            string data = "player_BuildingId=" + building.Id;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "升级建筑");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            XmlNode results = xml.SelectSingleNode("/results");
            XmlNodeList childs = results.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "maincitydto")
                {
                    XmlNodeList general_childs = child.ChildNodes;
                    building.fillValues(general_childs);
                }
                else if (child.Name == "outcitydto")
                {
                    XmlNodeList general_childs = child.ChildNodes;
                    building.fillValues(general_childs);
                }
                else if (child.Name == "constructordto")
                {
                    updateBuildLine(child.ChildNodes, buildingLines);
                }
            }
            logInfo(logger, String.Format("升级建筑 {0} {1}=>{2}, 花费{3}", building.Name, building.Level - 1, building.Level, cost));
            return true;
        }
        /// <summary>
        /// 是否有空闲队列
        /// </summary>
        /// <returns></returns>
        public bool hasEmptyLine(Dictionary<int, BuildingLine> buildingLines)
        {
            bool haveEmpty = false;
            foreach (BuildingLine timeline in buildingLines.Values)
            {
                if (!timeline.AlreadyCd) { haveEmpty = true; break; }
            }
            return haveEmpty;
        }
        public long recentLineCd(Dictionary<int, BuildingLine> buildingLines)
        {
            long cdtime = -1;
            foreach (BuildingLine timeline in buildingLines.Values)
            {
                if (cdtime < 0 || cdtime > timeline.CdTime) cdtime = timeline.CdTime;
            }
            return cdtime;
        }
    }
}
